package com.xiang.sql.service;

import java.util.ArrayList;
import java.util.List;

import jakarta.annotation.Resource;

import org.springframework.stereotype.Service;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiang.api.Util;
import com.xiang.sql.entity.User;
import com.xiang.sql.StaticSql;
import com.xiang.sql.entity.Stock;
import com.xiang.sql.entity.StockLog;
import com.xiang.sql.mapper.StockLogMapper;

/**
 * 库存变动日志 服务实现类
 * 
 * @author mac-xiang
 */
@Service
public class StockLogService extends ServiceImpl<StockLogMapper, StockLog> {
  @Resource
  StockLogMapper mapper;

  private QueryWrapper<StockLog> readWrapper(JSONObject p, User per) {
    QueryWrapper<StockLog> ret = Util.getQuery(p, StockLog.class, "a");
    if (per != null && !per.per("库存变动日志查询")) {
      ret.eq("a.`user`", per.id);
    }
    return ret;
  }

  private List<StockLog> getList(QueryWrapper<StockLog> q) {
    return mapper.selectList2(q);
  }

  private List<StockLog> getList(JSONObject p, User per) {
    return getList(readWrapper(p, per));
  }

  private final static String limit = " LIMIT %d,%d";

  private Page<StockLog> getPage(Page<StockLog> page, JSONObject p, User per) {
    QueryWrapper<StockLog> q = readWrapper(p, per);
    page.setTotal(mapper.count2(q));
    final long c = page.getCurrent(), s = page.getSize();
    List<StockLog> d = getList(readWrapper(p, per).last(String.format(limit, s * (c - 1), s)));

    page.setRecords(d);
    return page;
  }

  public Object read(JSONObject p, User per) {
    Page<StockLog> page = Util.getPage(p, StockLog.class);
    return page == null ? getList(p, per) : getPage(page, p, per);
  }

  public List<StockLog> log(JSONObject p, User per) {
    QueryWrapper<StockLog> ret = new QueryWrapper<>();
    String id = p.getString("id");
    if (!per.per("库存变动日志查询") && !per.per("单据查询")
        && !StaticSql.service.orderStock.have(id, per) && !StaticSql.service.order.have(id, per)) {
      throw new RuntimeException("没有权限");
    }
    return mapper.selectList2(ret.eq("a.oid", id));
  }

  public void create(List<StockLog> s) {
    final String vs = "  ('%s', '%s', '" + Util.sTime() + "', '%s', '%s', '%d', '%s'),";
    List<String> sql = new ArrayList<>(), a = new ArrayList<>();
    a.add("INSERT INTO `stock_log` (`id`, `redress`, `create_time`, `user`, `stock`, `sum`, `des`) VALUES");
    sql.add("START TRANSACTION;");
    for (StockLog e : s) {
      a.add(String.format(vs, e.id, e.redress, e.user, e.stock, e.sum, e.des));
      sql.add(String.format("UPDATE `stock` SET `sum` = `sum`%s WHERE id = '%s';",
          (e.sum >= 0 ? "+" : "") + String.valueOf(e.sum), e.stock));
    }
    String t = String.join("\n", a);
    sql.add(t.substring(0, t.length() - 1) + ";");
    sql.add("COMMIT;");
    StaticSql.run.select(String.join("\n", sql));
    // System.out.println(String.join("\n", sql));
  }

  final public String errNullSum = "第[%d]行数量不能为空";

  public List<StockLog> check(List<StockLog> d, String create, String oid, String inGid, String outGid) {
    if (d == null) {
      throw new RuntimeException("出入库记录为空");
    }
    int rote = -1;
    if (!StaticSql.service.group.exists(outGid)) {
      rote = 1;
    }
    if (!StaticSql.service.group.exists(inGid)) {
      if (rote > 0) {
        throw new RuntimeException("入库商户id错误:" + inGid);
      }
    }
    int i = 0;
    StockLog e;
    Stock s;
    while (i < d.size()) {
      e = d.get(i++);
      if (e.sum == null || e.sum == 0) {
        throw new RuntimeException(String.format(this.errNullSum, i));
      }
      e.sum = Math.abs(e.sum) * rote;
      try {
        s = StaticSql.service.stock.getFullByGG(outGid, e.goods);
        e.stock = s.id;
        if (s.goodsName == null || s.groupName == null) {
          throw null;
        }
        e.groupName = s.groupName;
        e.goodsMoney = s.goodsMoney;
        e.goodsName = s.goodsName;
      } catch (Exception _e) {
        throw new RuntimeException(String.format("第[%d]行商品已失效,请删除后重新下单", i));
      }
      e.id = Util.sGetId();
      e.id = Util.sGetId();
      e.oid = oid;
      e.state = 0;
      if (e.redress == null) {
        e.redress = "";
      }
      e.createTime = Util.time();
      e.user = create;
      if (e.des == null) {
        e.des = "";
      }
    }
    return d;
  }

  public List<StockLog> checkWithOrder(List<StockLog> d, String create, String oid, String outGid) {
    if (d == null) {
      throw new RuntimeException("出入库记录为空");
    }
    if (!StaticSql.service.group.exists(outGid)) {
      throw new RuntimeException("商户id错误:" + outGid);
    }
    int i = 0;
    StockLog e;
    Stock s;
    while (i < d.size()) {
      e = d.get(i++);
      if (e.sum == null || e.sum == 0) {
        throw new RuntimeException(String.format(this.errNullSum, i));
      }
      e.sum = -Math.abs(e.sum);
      try {
        s = StaticSql.service.stock.getFullByGG(outGid, e.goods);
        e.stock = s.id;
        if (s.goodsName == null || s.groupName == null) {
          throw null;
        }
        e.groupName = s.groupName;
        e.goodsMoney = s.goodsMoney;
        e.goodsName = s.goodsName;
      } catch (Exception _e) {
        throw new RuntimeException(String.format("第[%d]行商品已失效,请删除后重新下单", i));
      }
      e.id = Util.sGetId();
      e.oid = oid;
      e.state = 0;
      if (e.redress == null) {
        e.redress = "";
      }
      e.createTime = Util.time();
      e.user = create;
      if (e.des == null) {
        e.des = "";
      }
    }
    return d;
  }

  public List<StockLog> getByOid(String oid) {
    return mapper.selectList2(new QueryWrapper<StockLog>().eq("a.oid", oid));
  }

  private static final String upStockSql = "UPDATE `stock` SET `sum`=`sum`%s%d WHERE `id`='%s';\n";
  private static final String sendSql = "UPDATE `stock_log` SET `state`=1 WHERE `oid`='%s' AND `state`=0 AND `sum`<0;\n";
  private static final String recvSql = "UPDATE `stock_log` SET `state`=1 WHERE `oid`='%s' AND `state`=0 AND `sum`>0;\n";

  public String send(String oid) {
    List<StockLog> sl = mapper.selectList(new QueryWrapper<StockLog>().eq("oid", oid).eq("`state`", 0).lt("`sum`", 0));
    StringBuilder sb = new StringBuilder();
    sb.append(String.format(sendSql, oid));
    if (sl.size() > 0) {
      sl.forEach(e -> {
        sb.append(String.format(upStockSql, "", e.sum, e.stock));
      });
    }
    return sb.toString();
  }

  public String recv(String oid) {
    List<StockLog> sl = mapper.selectList(new QueryWrapper<StockLog>().eq("oid", oid).eq("`state`", 0).gt("`sum`", 0));
    StringBuilder sb = new StringBuilder();
    sb.append(String.format(recvSql, oid));
    if (sl.size() > 0) {
      sl.forEach(e -> {
        sb.append(String.format(upStockSql, "+", e.sum, e.stock));
      });
    }
    return sb.toString();
  }

}
